package com.naiterui.ehp.bs.patient.service.impl;

import com.naiterui.common.repository.page.CustomizedPageConvertor;
import com.naiterui.common.repository.page.PageParamVO;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.bo.recommend.MedicationRecomItemPaBO;
import com.naiterui.ehp.bp.bo.recommend.MedicationRecomPaBO;
import com.naiterui.ehp.bp.domain.Doctor;
import com.naiterui.ehp.bp.domain.Patient;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.utils.JsonMapper;
import com.naiterui.ehp.bs.patient.dao.IDoctorDao;
import com.naiterui.ehp.bs.patient.dao.IPatientDao;
import com.naiterui.ehp.bp.domain.PatientInquirerInfo;
import com.naiterui.ehp.bs.patient.exception.ExceptionCodes;
import com.naiterui.ehp.bs.patient.feign.RecomFeginClient;
import com.naiterui.ehp.bs.patient.repository.IApDoctorRepository;
import com.naiterui.ehp.bs.patient.repository.IApPatientRepository;
import com.naiterui.ehp.bs.patient.repository.IPatientInquirerRepository;
import com.naiterui.ehp.bs.patient.service.IMedicationRecomService;
import com.naiterui.ehp.bs.patient.utils.exception.PatientBusinessException;
import com.naiterui.ehp.bs.patient.vo.consult.MedicationRecomItemVO;
import com.naiterui.ehp.bs.patient.vo.consult.MedicationRecomVO;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 推荐用药业务接口实现
 *
 * @author Amber
 * @since 1.0.0
 */
@Service
public class ApMedicationRecomServiceImpl implements IMedicationRecomService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApMedicationRecomServiceImpl.class);

    @Autowired
    private IPatientDao patientDao;

    @Autowired
    private IDoctorDao doctorDao;

    @Autowired
    private RecomFeginClient recomFeginClient;
    @Autowired
    private IApDoctorRepository doctorRepository;
    @Autowired
    private IApPatientRepository patientRepository;

    @Autowired
    private IPatientInquirerRepository patientInquirerRepository;

    @Override
    public PageVO<MedicationRecomVO> getRecomDrugList(Long patientId, Long doctorId, Long consultId, PageParamVO pageParam) throws BusinessException {

        // 用户校验
        Patient patient = this.patientDao.get(patientId);
        // 患者不存在
        if (patient == null) {
            LOGGER.error("getConsultSessions Error ; patient not exist : patientId {}", patientId);
            throw new PatientBusinessException(ExceptionCodes.PATIENT_NOT_EXIST);
        }
        // 患者账号被禁用
        if (patient.getAccountStatus() != 0) {
            LOGGER.error("getConsultSessions Error ; patient account status wrong : patientId {}", patientId);
            throw new PatientBusinessException(ExceptionCodes.PATIENT_ACCOUNT_ERROR);
        }

        // 分页信息
        PageVO<MedicationRecomVO> recomPageVO = new PageVO<>();
        // 结果集
        List<MedicationRecomVO> recomVOs = new ArrayList<>();

        PageVO<MedicationRecomPaBO> recomPage = this.recomFeginClient.getRecomDrugList(patientId, doctorId, consultId, pageParam.getPage(),
            pageParam.getNum());
        Set<Long> doctorIds = new HashSet<>();
        for (MedicationRecomPaBO vo : recomPage.getResult()) {
            doctorIds.add(vo.getDoctorId());
        }
        // 推荐记录列表对应医生名称。key：医生id，value：医生姓名
        Map<Long, Doctor> doctorMap = this.doctorDao.getDoctorInfoByDrIds(doctorIds);
        // 推荐列表ids
        for (MedicationRecomPaBO vo : recomPage.getResult()) {
            MedicationRecomVO mrVo = new MedicationRecomVO();
            mrVo.setDoctorId(vo.getDoctorId());
            Doctor doctor = doctorMap.get(vo.getDoctorId());
            // 根据推荐的医生id获取医生姓名
            if (doctor != null) {
                mrVo.setAuthStatus(doctor.getStatus());
                mrVo.setDoctorName(doctor.getName());
            }
            mrVo.setRecomId(vo.getRecomId());
            mrVo.setRecomTime(vo.getRecomTime());
            mrVo.setPatientId(patientId);
            List<MedicationRecomItemVO> mvItemList = new ArrayList<>();
            for (MedicationRecomItemPaBO itemPaVo : vo.getItems()) {
                MedicationRecomItemVO itemVo = new MedicationRecomItemVO();
                itemVo.setBakup(itemPaVo.getBakup());
                itemVo.setCommonName(itemPaVo.getCommonName());
                itemVo.setProductId(itemPaVo.getPid());
                itemVo.setProductName(itemPaVo.getName());
                itemVo.setQuantity(itemPaVo.getQuantity());
                itemVo.setSkuId(itemPaVo.getSkuId());
                itemVo.setUsage(itemPaVo.getUsages());
                mvItemList.add(itemVo);
            }
            mrVo.setItems(mvItemList);
            mrVo.setDiagnosis(vo.getDiagnosis());// 处方笺临床诊断
            recomVOs.add(mrVo);
        }
        // 处理分页信息
        recomPageVO = CustomizedPageConvertor.buildPageVOWithCustom(recomPage.getPageNo(), recomPage.getPageSize(), recomVOs,
            recomPage.getTotalCount());
        return recomPageVO;
    }

    @Override
    public PageVO<MedicationRecomPaBO> getPrescriptionList(Integer page, Integer num, Long patientId, Integer status, Integer type) throws BusinessException {
        PageVO<MedicationRecomPaBO> pageInfo = this.recomFeginClient.getPatientRecomList(patientId, page, num, status , type);
        List<MedicationRecomPaBO> recomPaBOS = pageInfo.getResult();
        LOGGER.info("获取到患者处方列表数据信息 {}", JsonMapper.toJson(pageInfo));
        if (CollectionUtils.isNotEmpty(recomPaBOS)) {
            Map<Long, Doctor> doctorMap = new HashMap<>();
            Map<Long, PatientInquirerInfo> inquirerInfoMap = new HashMap<>();
            Set<Long> doctorIdSet = recomPaBOS.stream().map(e -> e.getDoctorId()).collect(Collectors.toSet());
            Set<Long> inquirerIdSet = recomPaBOS.stream().map(e -> e.getInquirerId()).collect(Collectors.toSet());
            List<Doctor> doctors = doctorRepository.findByIdIn(doctorIdSet);
            List<PatientInquirerInfo> inquirerInfos = patientInquirerRepository.findByIdIn(inquirerIdSet);
            doctorMap = doctors.stream().collect(Collectors.toMap(Doctor::getId, e -> e));
            inquirerInfoMap = inquirerInfos.stream().collect(Collectors.toMap(PatientInquirerInfo::getId, e -> e));
            for (MedicationRecomPaBO recomPaBO : recomPaBOS) {
                LOGGER.info("处理患者处方列表数据, 当前处理处方ID {}", recomPaBO.getRecomId());
                Doctor doctor = doctorMap.get(recomPaBO.getDoctorId());
                recomPaBO.setDoctorName(doctor.getName());
                PatientInquirerInfo patient = inquirerInfoMap.get(recomPaBO.getInquirerId());
                if (null != patient) {
                    recomPaBO.setPatientName(Optional.ofNullable(patient.getName()).orElse(""));
                }

            }
            PageVO result = PageVO.newBuilder()
                .pageNo(pageInfo.getPageNo())
                .pageSize(pageInfo.getPageSize())
                .totalCount(pageInfo.getTotalCount())
                .offset(pageInfo.getOffset())
                .result(recomPaBOS)
                .build();
            LOGGER.info("患者处方列表接口相应 {}", JsonMapper.toJson(result));
            return result;
        }

        return pageInfo;
    }
}
